package net.kazed.nextaction.database;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;

public class GtdContext /* implements BaseColumns */ {
   /**
    * The content:// style URL for this table
    */
   public static final Uri CONTENT_URI = Uri.parse("content://" + GtdAndroid.PACKAGE + "/context");
   public static final Uri CONTENT_ITEM_URI = Uri.parse("content://" + GtdAndroid.PACKAGE + "/context");
   public static final Uri cContextTasksContentURI = Uri.parse("content://" + GtdAndroid.PACKAGE + "/contextTasks");
   public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.nextaction.context";
   public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.nextaction.context";
   public static final String SELECTED_CONTEXT_ID = "selectedContextId";


   /**
    * The default sort order for this table
    */
   public static final String DEFAULT_SORT_ORDER = "name DESC";
   
   public static final String ID = BaseColumns._ID;
   public static final String NAME = "name";
   public static final String COLOUR = "colour";
   public static final String ICON = "iconId";
   public static final String PARENT_CONTEXT_ID = "parentContextId";
   
   public static final int ID_INDEX = 0;
   
   public static final Projection FULL_PROJECTION = new Projection(new String[] {ID, NAME, COLOUR, ICON, PARENT_CONTEXT_ID});
   
   public static final String TASK_COUNT = "count";

   /**
    * Projection for fetching the task count for each context.
    */
   public static final String[] cFullTaskProjection = new String[] {
        ID,
       TASK_COUNT,
   };
   
   private Integer id;
   private String name;
   private final Integer colourIndex;
   private final Integer iconResource;
   private Integer parentContextId;
   
   private int numberOfTasks;
   
   /**
    * Constructor.
    * @param id ID
    * @param name Name
    * @param colourIndex Color.
    * @param iconResource Icon.
    */
   public GtdContext(Integer id, String name, int colourIndex, Integer iconResource) {
      this.id = id;
      this.name = name;
      this.colourIndex = colourIndex;
      this.iconResource = iconResource;
   }
   
   /**
    * Constructor.
    * @param name Name
    * @param colourIndex Color.
    * @param iconResource Icon.
    */
   public GtdContext(String name, int colour, Integer iconResource) {
      this(null, name, colour, iconResource);
   }
   
   /**
    * Constructor.
    * @param name Name
    */
   public GtdContext(String name) {
      this(null, name, 0, null);
   }
   
   /**
    * Constructor.
    * @param cursor Construct context contents from this cursor.
    */
   public GtdContext(Cursor cursor) {
      Projection projection = GtdContext.FULL_PROJECTION;
      this.id = projection.getInteger(cursor, GtdContext.ID);
      this.name = projection.getString(cursor, GtdContext.NAME);
      this.colourIndex = projection.getInteger(cursor, GtdContext.COLOUR);
      this.iconResource = projection.getInteger(cursor, GtdContext.ICON);
      this.parentContextId = projection.getInteger(cursor, GtdContext.PARENT_CONTEXT_ID);
   }
   
   /**
    * @return The id
    */
   public Integer getId() {
      return id;
   }

   /**
    * @param id The id to set
    */
   public void setId(Integer id) {
      this.id = id;
   }

   /**
    * @return The name
    */
   public String getName() {
      return name;
   }

   /**
    * @param name The name
    */
   public void setName(String name) {
      this.name = name;
   }

   /**
    * @return The colourIndex
    */
   public int getColourIndex() {
      return colourIndex;
   }

   /**
    * @return The iconResource
    */
   public Integer getIconResource() {
      return iconResource;
   }

   /**
    * @return The parentContextId
    */
   public Integer getParentContextId() {
      return parentContextId;
   }

   /**
    * @param parentContextId The parentContextId to set
    */
   public void setParentContextId(Integer parentContextId) {
      this.parentContextId = parentContextId;
   }

   /**
    * @return The numberOfTasks
    */
   public int getNumberOfTasks() {
      return numberOfTasks;
   }

   /**
    * @param numberOfTasks The numberOfTasks to set
    */
   public void setNumberOfTasks(int numberOfTasks) {
      this.numberOfTasks = numberOfTasks;
   }

   /**
    * Copy attributes to values.
    * @param values Values of model attributes.
    */
   public void toValues(ContentValues values) {
      values.put(NAME, name);
      values.put(COLOUR, colourIndex);
      values.put(ICON, iconResource);
      values.put(PARENT_CONTEXT_ID, parentContextId);
   }
   
   /**
    * Get parent context.
    * @param resolver Database provider.
    * @return Parent context.
    */
   public GtdContext getParentContext(ContentResolver resolver) {
      GtdContext context = null;
      if (parentContextId != null) {
         Uri parentUri = ContentUris.withAppendedId(GtdContext.CONTENT_ITEM_URI, parentContextId);
         Cursor cursor = resolver.query(parentUri, FULL_PROJECTION.getFieldNames(), null, null, null);
         if (cursor.moveToFirst()) {
            context = new GtdContext(cursor);
         }
         cursor.close();
      }
      return context;
   }
   
   /**
    * Get absolute path to this context
    * @param resolver Database resolver.
    * @param divider Divider between context names.
    * @return Constructed path from top-most context to this context.
    */
   public String getAbsoluteContextPath(ContentResolver resolver, String divider) {
      StringBuffer resultPath = new StringBuffer();
      appendAbsolutePath(resolver, divider, resultPath);
      return resultPath.toString();
   }

   /**
    * Append path of parent and the name of this context to path.
    * @param resolver Database resolver.
    * @param divider Divider between context names.
    * @param path Constructed path from top-most context to this context.
    */
   private void appendAbsolutePath(ContentResolver resolver, String divider, StringBuffer path) {
      GtdContext parent = getParentContext(resolver);
      if (parent != null) {
         parent.appendAbsolutePath(resolver, divider, path);
         path.append(divider);
      }
      path.append(name);
   }

}
